#ifndef __CRYGAMESPYVOICE_H__
#define __CRYGAMESPYVOICE_H__

#pragma once

#include "Lobby/CryVoice.h"

#if USE_CRYLOBBY_GAMESPY && USE_CRYLOBBY_GAMESPY_VOIP

#include "Gamespy2.11.00/Source/Voice2/gv.h"

#define MAX_GAMESPY_VOIP_DEVICES (16)
#define GAMESPY_VOICE_BUFFER_SIZE (512)

#define MAX_GAMESPY_LOCAL_TALKERS			1
#define MAX_GAMESPY_REMOTE_TALKERS		16

class CCryGameSpyVoice : public CCryVoice
{
	typedef CCryVoice PARENT;

public:
																	CCryGameSpyVoice(CCryLobby* pLobby, CCryLobbyService* pService);

					ECryLobbyError					Initialise();
					ECryLobbyError					Terminate();
					void										Tick(CTimeValue tv);
					void										OnPacket(const TNetAddress& addr, CCryLobbyPacket* pPacket);

					CryVoiceRemoteUserID		RegisterRemoteUser(CryLobbyConnectionID connectionID, CryUserID remoteUserID);
					void										UnRegisterRemoteUser(CryLobbyConnectionID connectionID);

					void										LateSetUserLobbyConnection( CryLobbyConnectionID connectionID, CryUserID remoteUserID );

					void										EnablePushToTalk(uint32 localUser, bool bSet);
					bool										IsPushToTalkEnabled(uint32 localUser);
					void										PushToTalkButtonDown(uint32 localUser);
					void										PushToTalkButtonUp(uint32 localUser);
					void										SetVoicePlaybackVolume(uint32 localUser, float volume);
					float										GetVoicePlaybackVolume(uint32 localUser);


					virtual bool						IsSpeaking(uint32 localUser);
					virtual bool						IsMicrophoneConnected(CryUserID userID);

protected:
					ECryLobbyError					InitDevices();
					void										SendVoiceData(void);
					void										ProcessVoiceData(const TNetAddress& addr, CCrySharedLobbyPacket* pPacket);

					bool										CreateDevice(GVDevice& device, GVDeviceType deviceType, uint32 deviceInfoIndex);
					void										FreeDevice(GVDevice& device, GVDeviceType deviceType);

					uint32									CaptureVoiceData(void);
					void										PlayVoiceData(GVByte* pData, int32 dataSize, CryVoiceRemoteUserID userID, GVFrameStamp& frameStamp);

	static	void										VOIPEnabledChanged(ICVar* pCVar);
	static	void										VOIPPushToTalkChanged(ICVar* pCVar);
	static	void										VOIPPlaybackVolumeChanged(ICVar* pCVar);

	virtual void										SendMicrophoneNotification(uint32 remoteUserID);
	virtual void										SendMicrophoneRequest(uint32 remoteUserID);
	void														ProcessMicrophoneNotification(const TNetAddress& addr, CCryLobbyPacket* pPacket);
	void														ProcessMicrophoneRequest(const TNetAddress& addr, CCryLobbyPacket* pPacket);

private:
	struct SLocalUser
	{
		GVByte					m_captureBuffer[GAMESPY_VOICE_BUFFER_SIZE];
		int32						m_numCapturedBytes;
		GVScalar				m_capturePeakVolume;
		GVFrameStamp		m_frameStamp;
		uint32					m_localUserFlags;
		GVScalar				m_playbackVolume;
		bool						m_bPushToTalkEnabled;
		bool						m_bPushToTalkDown;
	}									m_localUser;
	SRemoteUser				m_remoteUsers[MAX_GAMESPY_REMOTE_TALKERS];
	SUserRelationship	m_userRelationship[MAX_GAMESPY_LOCAL_TALKERS][MAX_GAMESPY_REMOTE_TALKERS];

	GVDeviceInfo			m_deviceInfo[MAX_GAMESPY_VOIP_DEVICES];
	GVDevice					m_captureDevice;
	GVDevice					m_playbackDevice;
	uint32						m_deviceInfoCount;

	SCryGameSpyVoiceCodecInfo* m_pGameSpyVoiceCodecInfo;
	CTimeValue				m_lastTickTime;
	bool							m_initialised;
};

#endif // USE_CRYLOBBY_GAMESPY && USE_CRYLOBBY_GAMESPY_VOIP

#endif // __CRYGAMESPYVOICE_H__
// [EOF]
